package net;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.DatagramPacket;
import java.net.InetAddress;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import logic.Team;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class HandshakeMsg implements NetMessage{
	private String playerName;
	private String md5State;
	private Team color;
	
	
	public HandshakeMsg(String playerName){
		this.playerName = playerName;
	}
	
	public String getPlayer(){
		return playerName;
	}
	
	
	public void setColor(Team color){
		this.color = color;
	}
	
	public Team getColor(){
		return color;
	}
	
	public void setMD5State(String md5State){
		this.md5State = md5State;
	}
	
	public String getMD5State(){
		return md5State;
	}
	
	private Document getXMLString(){
		try {
			DocumentBuilder docB = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			Document msg = docB.newDocument();
			Element handshake  = msg.createElement(GameNetMessages.khetMsg);
			handshake.setAttribute("player", playerName);
			handshake.setAttribute("type", GameNetMessages.handshake);
			if(color!=null)
				handshake.setAttribute("color", color.toString().toLowerCase());
			if(md5State!=null)
				handshake.setAttribute("gameState", md5State);
			msg.appendChild(handshake);
			return msg;
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static HandshakeMsg parseDatagram(DatagramPacket packet) throws ParserConfigurationException, SAXException, IOException {
		HandshakeMsg handshake;
		String message = new String(packet.getData()).trim();
		DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        InputSource is = new InputSource();
        is.setCharacterStream(new StringReader(message));
        Document doc = db.parse(is);
        doc.normalize();
        NodeList msgElements = doc.getElementsByTagName("khetMessage");
        
        for(int i=0;i<msgElements.getLength();i++){
        	Element khetMessage;
        	if(!(msgElements.item(i) instanceof Element))
        		continue;
        	khetMessage = (Element)msgElements.item(i);
        	String msgType = khetMessage.getAttribute("type");
        	String playerName= khetMessage.getAttribute("player");
        	String color = khetMessage.getAttribute("color");
        	String md5 = khetMessage.getAttribute("gameState");
        	if(msgType.equals(GameNetMessages.handshake)){
        		if(playerName==null)
        			return null;
        		handshake = new HandshakeMsg(playerName);

        		if(color!=null){
        			if(color.equals("red"))
        				handshake.setColor(Team.RED);
        			if(color.equals("gray"))
        				handshake.setColor(Team.GRAY);
        		}
        		if(md5!=null)
        			handshake.setMD5State(md5);
        		return handshake;
        	}
        }
		return null;
	}

	@Override
	public DatagramPacket getMsgPacket(InetAddress dst, int port) {
		Document msgXML = getXMLString();
		if(msgXML==null)
			return null;
		Transformer transformer;
		try {
			transformer = TransformerFactory.newInstance().newTransformer();
			transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
			transformer.setOutputProperty(OutputKeys.INDENT, "no");

			StreamResult result = new StreamResult(new StringWriter());
			DOMSource source = new DOMSource(msgXML);
			transformer.transform(source, result);
			String hsXML = result.getWriter().toString();
			byte[] buf = hsXML.getBytes();
			return new DatagramPacket(buf, buf.length, dst, port);
		} catch (TransformerConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerFactoryConfigurationError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

}
